package cn.lynch.bbs.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import cn.lynch.bbs.dao.CategoryDao;
import cn.lynch.bbs.dao.PropertyFilter;
import cn.lynch.bbs.domain.Category;
import cn.lynch.bbs.service.CategoryService;
@Service
public class CategoryServiceImpl implements CategoryService {

	@Autowired
	private CategoryDao categoryDao;
	
	@Override
	public void createCategory(Category category) {
		Assert.notNull(category);
		categoryDao.save(category);
	}

	@Override
	public List<Category> findAllCategories() {
		return categoryDao.findAll();
	}

	@Override
	public Category findCategory(String categoryId) {
		return categoryDao.findByIdentifier(categoryId);
	}

	@Override
	public boolean moveCategory(String categoryId, boolean up) {
		
		Category categoryToMove = categoryDao.findByIdentifier(categoryId);
		
		int maxDisplayIdx = categoryDao.findMaxDisplayIndex();
		int currentIdx = categoryToMove.getDisplayIndex();
		
		if (currentIdx > 1 && currentIdx < maxDisplayIdx ) {
			
			Category neighbor = findNeighborCategory(categoryToMove, up);
			
			swapIndex(categoryToMove, neighbor);
			
			categoryDao.update(categoryToMove);
			categoryDao.update(neighbor);
			
			return true;
		}
		
		return false;
	}
	
	private void swapIndex(Category categoryToMove, Category neighbor) {
		int neighborIdx = neighbor.getDisplayIndex();
		neighbor.setDisplayIndex(categoryToMove.getDisplayIndex());
		categoryToMove.setDisplayIndex(neighborIdx);
	}

	private Category findNeighborCategory(Category category, boolean up) {
		
		PropertyFilter filter = PropertyFilter.createFilter(Category.class);
			
		if (up) {
			filter.lt("displayIndex", category.getDisplayIndex())
				.desc("displayIndex");
		} else {
			filter.gt("displayIndex", category.getDisplayIndex())
				.asc("displayIndex");
		}
		
		return categoryDao.findByFilter(filter);
	}

	@Override
	public void removeCategory(String categoryId) {
		categoryDao.remove(categoryId);
	}

	@Override
	public void updateCategory(Category category) {
		categoryDao.update(category);
	}

}
